#!/bin/bash

# Place this file at your .git root dir ,and run it by shell
# 2025.02.17.wood
# modified: 2025.02.18.wood



# 定义日志开关
# 0：不进行输出任何信息
# 1：只对任何错误或异常输出，显示屏不打印任何信息
# 2：只对任何错误或异常输出，显示屏打印任何信息
# 3：成功操作的信息也全部输出，显示屏不打印任何信息
# 4：成功操作的信息也全部输出，显示屏打印任何信息
log_switch=4



# 定义Git仓库路径，需要替换为你实际的Git仓库路径
git_repository_path="/path/to/your/git/repository"
custom_str="自定义成功提交时的字符串1"

# 定义日志文件路径
log_file="/path/to/your/log/file.log"

# 远程仓库名称（如 origin）
REMOTE_NAME="origin"

# 远程分支名称（如 master/main）
REMOTE_BRANCH="master"

# Git可执行文件路径（默认用系统PATH中的git，可自定义）
GIT_BIN="/usr/bin/git"
### 核心配置区结束 ###





# 日志输出函数（优化版：用case简化逻辑）
log_output() {
  local is_error=$1
  local log_message=$2
  local print_screen=$3
  local log_prefix="$(date +%Y%m%d%H%M%S) - "

  case $log_switch in
    0)  return ;;
    1)  [ $is_error -eq 1 ] && echo "${log_prefix}${log_message}" >> "$log_file" ;;
    2)  if [ $is_error -eq 1 ]; then
          echo "${log_prefix}${log_message}" >> "$log_file"
          [ $print_screen -eq 1 ] && echo "${log_prefix}${log_message}"
        fi ;;
    3)  echo "${log_prefix}${log_message}" >> "$log_file" ;;
    4)  echo "${log_prefix}${log_message}" >> "$log_file"
        [ $print_screen -eq 1 ] && echo "${log_prefix}${log_message}" ;;
    *)  return ;;
  esac
}


# 1. 校验Git可执行性
if ! command -v "$GIT_BIN" >/dev/null 2>&1; then
  log_output 1 "Git命令未找到，请检查 \$GIT_BIN 配置: $GIT_BIN" 1
  exit 1
fi


# 2. 进入Git仓库目录（带路径校验）
if [ ! -d "$git_repository_path" ]; then
  log_output 1 "Git仓库路径不存在: $git_repository_path" 1
  exit 1
fi

cd "$git_repository_path" || {
  log_output 1 "进入仓库目录失败: $git_repository_path" 1
  exit 1
}


# 3. 检查Git仓库合法性（是否存在.git目录）
if [ ! -d ".git" ]; then
  log_output 1 "当前目录不是有效的Git仓库: $git_repository_path" 1
  exit 1
fi


# 4. 拉取并合并远程更新
pull_output=$($GIT_BIN pull "$REMOTE_NAME" "$REMOTE_BRANCH")
pull_status=$?

if [ $pull_status -ne 0 ]; then
  log_output 1 "拉取并合并失败，错误信息: $pull_output" 1
  exit 1
elif echo "$pull_output" | grep -q "Already up to date"; then
  log_output 0 "远程仓库没有更新，本地已是最新状态" 1
  exit 0
fi


# 5. 检查本地是否有更改
if [ -z "$($GIT_BIN status --porcelain)" ]; then
  log_output 0 "本地没有任何变化，无需提交" 1
  exit 0
fi


# 6. 生成提交信息 & 提交更改
commit_msg="${custom_str}_$(date +%Y%m%d%H%M%S)"

$GIT_BIN add .

$GIT_BIN commit -m "$commit_msg"
commit_status=$?
if [ $commit_status -ne 0 ]; then
  error_msg=$($GIT_BIN commit -m "$commit_msg" 2>&1)
  log_output 1 "提交失败，错误信息: $error_msg" 1

  # 回滚暂存区，避免脏数据残留
  $GIT_BIN reset HEAD . >/dev/null 2>&1
  exit 1
fi


# 7. 推送本地更新到远程仓库
push_output=$($GIT_BIN push "$REMOTE_NAME" "$REMOTE_BRANCH" 2>&1)
push_status=$?
if [ $push_status -ne 0 ]; then
  log_output 1 "推送失败，错误信息: $push_output" 1
  echo "提交并推送时出错"
  exit 1
fi


# 8. 输出成功结果
log_output 0 "成功提交并推送本地更新到远程仓库" 1
